/*
 * // +-------------------------------------------------------------------------------------------------
 * // |                 有你就好 [ 有节骨乃坚，无心品自端 ]     <http://encoding.wang>
 * // +-------------------------------------------------------------------------------------------------
 * // |                             独在异乡为异客         每逢佳节倍思亲
 * // +-------------------------------------------------------------------------------------------------
 * // |                 联系:   <707069100@qq.com>      <http://weibo.com/513778937>
 * // +-------------------------------------------------------------------------------------------------
 */

// -----------------------------------------------------------------------------------------------------
// +----------------------------------------------------------------------------------------------------
// |                   ErYang出品 属于小极品          共同学习    共同进步
// +----------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------


package wang.encoding.mroot.common.util;


import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.TreeMap;


/**
 * 参数加密工具类
 * 单利模式
 *
 * @author ErYang
 */
public class CreateSignUtil {


    /**
     * 签名秘钥
     */
    private static final String SIGN_SECRET = "11498C36FCDFD439";

    /**
     * 禁止实例化
     */
    private CreateSignUtil() {

    }

    // -------------------------------------------------------------------------------------------------

    private static volatile CreateSignUtil createSignUtil;

    // -------------------------------------------------------------------------------------------------

    public static CreateSignUtil getCreateSignUtil() {
        if (null == createSignUtil) {
            synchronized (CreateSignUtil.class) {
                if (null == createSignUtil) {
                    createSignUtil = new CreateSignUtil();
                }
            }
        }
        return createSignUtil;
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 检查请求的签名
     *
     * @param paramsSign 参数加密
     * @param sign       签名
     * @return Boolean
     */
    public Boolean checkSign(final String paramsSign, final String sign) {
        if (StringUtils.isBlank(paramsSign) || StringUtils.isBlank(sign)) {
            return false;
        }
        if (paramsSign.equals(sign)) {
            return true;
        } else {
            return false;
        }
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 给请求参数签名
     *
     * @param sortedParams 所有字符型的请求参数
     * @param secret       签名密钥
     * @return 签名
     * @throws java.io.IOException
     */
    public static String createSign(final TreeMap<String, Object> sortedParams, final String secret)
            throws IOException {
        // 第一步：把字典按 Key 的字母顺序排序
        TreeMap<String, Object> tree = sortedParams;


        // 第二步：把所有参数名和参数值串在一起
        StringBuilder query = new StringBuilder(secret);
        for (Map.Entry<String, Object> entry : tree.entrySet()) {
            if (StringUtils.isNotBlank(entry.getKey())) {
                //query.append(entry.getKey()).append("==").append(entry.getValue()).append(";");
                query.append(entry.getKey()).append(entry.getValue());
            }
        }

        System.out.println("加密前：" + query.toString());
        // 第三步：使用MD5加密
        MessageDigest md5 = getMd5MessageDigest();
        byte[] bytes = md5.digest(query.toString().getBytes("UTF-8"));

        // 第四步：把二进制转化为大写的十六进制
        StringBuilder sign = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (1 == hex.length()) {
                sign.append("0");
            }
            sign.append(hex.toUpperCase());
        }
        System.out.println("加密后：" + sign.toString());
        return sign.toString();
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 得到md5
     *
     * @return
     * @throws IOException
     */
    private static MessageDigest getMd5MessageDigest() throws IOException {
        try {
            return MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new IOException(e.getMessage());
        }
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 测试
     *
     * @param args args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        // 不指定排序器
        TreeMap<String, Object> treeMap1 = new TreeMap<>();
        treeMap1.put("2", "2");
        treeMap1.put("b", "b");
        treeMap1.put("10", "10");
        treeMap1.put("1", "1");
        treeMap1.put("AB", "AB");
        treeMap1.put("ab", "ab");
        treeMap1.put("a", "a");
        treeMap1.put("A", "A");
        createSign(treeMap1, SIGN_SECRET);
    }

    // -------------------------------------------------------------------------------------------------

}
